package com.mall.security.common.manager;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mall.security.common.bo.TokenInfoBO;
import com.mall.security.common.bo.UserInfoBO;
import com.mall.security.common.vo.TokenInfoVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;

import static com.mall.common.utils.RedisEnums.LOGIN_TOKEN;

@Component
public class TokenManager {

    private final int TIMEOUT = 3600;

    private final Logger logger = LoggerFactory.getLogger(TokenManager.class);
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    /**
     * 完成用户登录功能  ，存储token 并展示token信息
     * refreshToken实现无感刷新登录
     * @param useInfo
     * @return
     */
    public TokenInfoVO storeTokenGetVO(UserInfoBO useInfo){
        if(!useInfo.isStatus()){
            throw new RuntimeException("用户被封禁");
        }
        //写一个统一登陆的方法
        //写道redis里面
        //实现简单的Outha2 功能
        TokenInfoBO tokenInfoBO = this.storeAccessToken(useInfo);
        TokenInfoVO tokenInfoVO = new TokenInfoVO();
        tokenInfoVO.setToken(tokenInfoBO.getToken());
        tokenInfoVO.setRefreshToken(tokenInfoBO.getRefreshToken());
        tokenInfoVO.setExpiredTime(tokenInfoBO.getExpiredTime());
        return tokenInfoVO;
    }

    /**
     *   存储accessToken
     * @param useInfo
     * @return
     */
    public TokenInfoBO storeAccessToken(UserInfoBO useInfo){
        /*if(useInfo==null){
            logger.error("token为空");
            throw new RuntimeException("token为空");
        }*/
        StpUtil.login(useInfo.getUserId());
        String tokenValue = StpUtil.getTokenValue();
        String keyName =LOGIN_TOKEN +tokenValue ;
        redisTemplate.opsForValue().set(
                keyName,
                JSON.toJSONString(useInfo),
                TIMEOUT,
                TimeUnit.SECONDS
        );
        TokenInfoBO tokenInfoBO =new TokenInfoBO();
        tokenInfoBO.setRefreshToken(tokenValue);
        tokenInfoBO.setToken(tokenValue);
        tokenInfoBO.setExpiredTime(TIMEOUT);
        tokenInfoBO.setUserInfoBO(useInfo);
        return tokenInfoBO;
    }

    /**
     * 刷新token
     * @param refreshToken
     * @return
     */
    public TokenInfoBO refreshToken(String refreshToken){
        String keyName =LOGIN_TOKEN +refreshToken ;
        Object object = redisTemplate.opsForValue().get(keyName);
        if(object==null){
            //不存在，抛出异常，直接登录
            logger.error("token过期");
            throw new RuntimeException("token过期,重新登录");
        }
        UserInfoBO userInfoBO = JSON.parseObject(refreshToken, UserInfoBO.class);
        this.deleteCurrentToken(refreshToken);
        return storeAccessToken(userInfoBO);
    }

    public void deleteCurrentToken(String refreshToken){
        String prefix = LOGIN_TOKEN + refreshToken;
        redisTemplate.delete(prefix);
        StpUtil.logoutByTokenValue(refreshToken);
    }




}
